/*
* Copyright 2005-2015 by BerryWorks Software, LLC. All rights reserved.
*
* This file is part of EDIReader. You may obtain a license for its use directly from
* BerryWorks Software, and you may also choose to use this software under the terms of the
* GPL version 3. Other products in the EDIReader software suite are available only by licensing
* with BerryWorks. Only those files bearing the GPL statement below are available under the GPL.
*
* EDIReader is free software: you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version.
*
* EDIReader is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with EDIReader. If not,
* see <http://www.gnu.org/licenses/>.
*/
package com.berryworks.edireader.util.dom;
import com.berryworks.edireader.EDIReader;
import com.berryworks.edireader.plugin.PluginControllerFactoryInterface;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.XMLReader;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMResult;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.sax.SAXSource;
import javax.xml.transform.stream.StreamResult;
import java.io.Writer;
import java.util.ArrayList;
import java.util.List;
/**
* Provides convenience methods for using the W3C DOM API in an EDI context.
* <p>
* These method are written using the EDIReader and DOM APIs and simply encapsulate
* functional sequences that may be useful for testing and other purposes.
*/
public class DocumentUtil {
private static final DocumentUtil instance = new DocumentUtil();
private DocumentUtil() {
}
/**
* Returns the instance of the singleton.
*
* @return the instance
*/
public static DocumentUtil getInstance() {
return instance;
}
/**
* Build a DOM from EDI input.
*
* @param inputSource EDI input
* @return Document representing parsed EDI content
* @throws Exception if problem reading or parsing input
*/
public synchronized Document buildDocumentFromEdi(InputSource inputSource) throws Exception {
return buildDocumentFromEdi(inputSource, null);
}
public synchronized Document buildDocumentFromEdi(InputSource inputSource, PluginControllerFactoryInterface factory) throws Exception {
EDIReader ediReader = new EDIReader();
if (factory != null) {
ediReader.setPluginControllerFactory(factory);
}
XMLReader xmlReader = ediReader;
Transformer transformer = TransformerFactory.newInstance().newTransformer();
DOMResult domResult = new DOMResult();
transformer.transform(new SAXSource(xmlReader, inputSource), domResult);
Document document = (Document) domResult.getNode();
if (document == null)
throw new RuntimeException("transform produced null document");
return document;
}
/**
* Build a DOM from XML input.
*
* @param inputSource XML input
* @return Document containing parsed XML content
* @throws Exception if problem reading or parsing input
*/
public synchronized Document buildDocumentFromXml(InputSource inputSource) throws Exception {
DocumentBuilderFactory factory =
DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(inputSource);
if (document == null)
throw new RuntimeException("parse produced null document");
return document;
}
public synchronized void writeXML(Document document, Writer writer) throws TransformerException {
StreamResult streamResult = new StreamResult();
streamResult.setWriter(writer);
Transformer transformer = TransformerFactory.newInstance().newTransformer();
transformer.transform(new DOMSource(document), streamResult);
}
public static Element position(Element origin, String[] path) {
Element e = origin;
for (String p : path) {
List<Element> children = getChildren(e, p);
if (children == null || children.size() < 1)
throw new RuntimeException("Cannot position to <" + p + ">");
e = children.get(0);
}
return e;
}
public static List<Element> getChildren(Element element) {
return getChildren(element, null);
}
public static List<Element> getChildren(Element element, String tag) {
List<Element> result = new ArrayList<>();
NodeList childNodes = element.getChildNodes();
for (int i = 0; i < childNodes.getLength(); i++) {
Node node = childNodes.item(i);
if (Node.ELEMENT_NODE == node.getNodeType()) {
// tag == null is considered a wildcard
if (tag == null || tag.equals(node.getNodeName())) {
result.add((Element) node);
}
}
}
return result;
}
public static Element getFirstChild(Element element, String tag) {
Element result = null;
NodeList childNodes = element.getChildNodes();
for (int i = 0; i < childNodes.getLength(); i++) {
Node node = childNodes.item(i);
if (Node.ELEMENT_NODE == node.getNodeType() && node.getNodeName().equals(tag)) {
result = (Element) node;
break;
}
}
return result;
}
public static List<Element> getChildrenHavingAttribute(Element element, String tag, String attrName, String attrValue) {
List<Element> result = new ArrayList<>();
if (attrName == null || attrValue == null) return result;
NodeList childNodes = element.getChildNodes();
for (int i = 0; i < childNodes.getLength(); i++) {
Node node = childNodes.item(i);
if (Node.ELEMENT_NODE == node.getNodeType() && node.getNodeName().equals(tag)) {
Element e = (Element) node;
if (attrValue.equals(e.getAttribute(attrName))) {
result.add(e);
}
}
}
return result;
}
}